package com.minelx.scriptbuilder.parse;

import com.minelx.scriptbuilder.script.attribute.clazz.Class;
import com.minelx.sequence.*;
import com.minelx.scriptbuilder.parse.parser.ClassesParser;
import com.minelx.scriptbuilder.parse.parser.FunctionDeclareOperationsParser;
import com.minelx.scriptbuilder.parse.parser.StatementsParser;
import com.minelx.scriptbuilder.script.ScriptContext;
import com.minelx.scriptbuilder.script.attribute.function.FunctionFactory;
import com.minelx.scriptbuilder.script.attribute.function.PrintFunction;
import com.minelx.scriptbuilder.script.attribute.function.SumFunction;
import com.minelx.scriptbuilder.script.operation.CompositeOperation;
import com.minelx.scriptbuilder.script.operation.IOperation;

import static com.minelx.sequence.Collector.toList;

public class ScriptInterpreter {

	private final CompositeMatcher<IOperation, IStringScanner> parsers;

	public ScriptInterpreter(ScriptContext context) {
		context.set("print", new PrintFunction(context));
		context.set("sum", new SumFunction());
		context.set("String", Class.stringClass());

		parsers = new CompositeMatcher<IOperation, IStringScanner>()
				.add(new ClassesParser(context, context))
				.add(new FunctionDeclareOperationsParser(context, context, new FunctionFactory()))
				.add(new StatementsParser(context))
		;
	}

	public IOperation interpret(String command) {
		TrimmedStringScanner scanner = new TrimmedStringScanner(new StringScanner(command));
		return new CompositeOperation().addAll(
				scanner.sequence(parsers).collect(toList())
		);
	}
}
